package com.snack.shop.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.snack.shop.common.BusinessException;
import com.snack.shop.common.OrderStatus;
import com.snack.shop.common.RefundStatus;
import com.snack.shop.entity.Order;
import com.snack.shop.mapper.OrderMapper;
import com.snack.shop.service.RefundService;
import com.snack.shop.service.SystemConfigService;
import com.snack.shop.service.WxPayService;
import com.snack.shop.service.MerchantMessageService;
import com.snack.shop.mapper.UserMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 退款服务实现
 * 
 * @author 阿狄
 * @date 2025-11-13
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class RefundServiceImpl implements RefundService {

    private final OrderMapper orderMapper;
    private final SystemConfigService systemConfigService;
    private final WxPayService wxPayService;
    private final MerchantMessageService merchantMessageService;
    private final UserMapper userMapper;

    @Override
    public Page<Order> getPendingRefunds(Integer current, Integer size) {
        Page<Order> page = new Page<>(current, size);
        
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getStatus, OrderStatus.REFUND_REVIEWING) // 退款审核中
                .eq(Order::getRefundStatus, RefundStatus.REVIEWING) // 退款审核中
                .orderByAsc(Order::getRefundApplyTime); // 按申请时间升序，先申请的先处理
        
        return orderMapper.selectPage(page, wrapper);
    }

    @Override
    public Page<Order> getProcessedRefunds(Integer current, Integer size) {
        Page<Order> page = new Page<>(current, size);
        
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Order::getRefundStatus, RefundStatus.SUCCESS, RefundStatus.REJECTED) // 退款成功或被拒绝
                .orderByDesc(Order::getUpdateTime); // 按更新时间降序
        
        return orderMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approveRefund(Long orderId, Boolean approved, BigDecimal compensationRate, String rejectReason) {
        // 1. 校验订单
        Order order = orderMapper.selectById(orderId);
        if (order == null) {
            throw new BusinessException("订单不存在");
        }
        
        if (!order.getStatus().equals(OrderStatus.REFUND_REVIEWING) || 
            !order.getRefundStatus().equals(RefundStatus.REVIEWING)) {
            throw new BusinessException("订单不在退款审核状态");
        }

        // 2. 根据审核结果处理
        if (approved) {
            // 同意退款
            if (isErrandOrder(order.getOrderType()) && compensationRate == null) {
                throw new BusinessException("代取订单退款必须设置补偿比例");
            }
            
            // 校验补偿比例范围
            if (compensationRate != null) {
                BigDecimal minRate = systemConfigService.getConfigValueAsDecimal("refund.compensation.rate.min", new BigDecimal("0.10"));
                BigDecimal maxRate = systemConfigService.getConfigValueAsDecimal("refund.compensation.rate.max", new BigDecimal("0.50"));
                
                if (compensationRate.compareTo(minRate) < 0 || compensationRate.compareTo(maxRate) > 0) {
                    throw new BusinessException("补偿比例必须在" + minRate.multiply(new BigDecimal("100")) + "%-" + maxRate.multiply(new BigDecimal("100")) + "%之间");
                }
            }
            
            processApprovedRefund(order, compensationRate);
        } else {
            // 拒绝退款
            if (rejectReason == null || rejectReason.trim().isEmpty()) {
                throw new BusinessException("拒绝退款必须填写原因");
            }
            processRejectedRefund(order, rejectReason);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void processApprovedRefund(Order order, BigDecimal compensationRate) {
        try {
            // 1. 计算退款和补偿金额
            BigDecimal[] amounts = calculateRefundAmount(order, compensationRate);
            BigDecimal refundAmount = amounts[0];
            BigDecimal compensationAmount = amounts[1];

            // 2. 调用微信退款接口
            String refundNo = wxPayService.refund(order, order.getCancelReason(), refundAmount);
            log.info("订单{}退款成功，退款单号：{}，退款金额：{}，补偿金额：{}", 
                    order.getOrderNo(), refundNo, refundAmount, compensationAmount);

            // 3. 更新订单状态
            order.setStatus(OrderStatus.REFUNDED); // 已退款
            order.setRefundStatus(RefundStatus.SUCCESS); // 退款成功
            order.setRefundAmount(refundAmount);
            order.setCompensationAmount(compensationAmount);
            order.setCancelTime(LocalDateTime.now());

            // 4. 处理补偿金（代取订单）
            if (compensationAmount.compareTo(BigDecimal.ZERO) > 0) {
                // 更新订单的骑手收益为补偿金额
                order.setRiderEarning(compensationAmount);
                updateRiderEarning(order.getDeliveryUserId(), compensationAmount);
            } else {
                // 如果没有补偿金，骑手收益为0
                order.setRiderEarning(BigDecimal.ZERO);
            }

            orderMapper.updateById(order);
            
            // 5. 为商家创建消息：退款已处理
            try {
                Long merchantId = getMerchantId();
                if (merchantId != null) {
                    String msg = "订单" + order.getOrderNo() + "退款已处理，退款金额¥" + refundAmount;
                    if (compensationAmount.compareTo(BigDecimal.ZERO) > 0) {
                        msg += "，补偿金¥" + compensationAmount;
                    }
                    merchantMessageService.create(merchantId, 2, "退款已处理", msg, "order", order.getId());
                }
            } catch (Exception e) {
                log.warn("创建商家消息失败, orderId={}", order.getId(), e);
            }
            
            // 6. 发送通知（TODO: 实现通知功能）
            log.info("订单{}退款处理完成，已通知相关用户", order.getOrderNo());
            
        } catch (Exception e) {
            log.error("订单{}退款处理失败", order.getOrderNo(), e);
            throw new BusinessException("退款处理失败：" + e.getMessage());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void processRejectedRefund(Order order, String rejectReason) {
        // 1. 恢复订单原状态
        Integer originalStatus = getOriginalStatus(order);
        order.setStatus(originalStatus);
        order.setRefundStatus(RefundStatus.REJECTED); // 退款被拒绝
        order.setRefundRejectReason(rejectReason);
        
        orderMapper.updateById(order);
        
        // 2. 发送通知给用户（TODO: 实现通知功能）
        log.info("订单{}退款被拒绝，原因：{}，已通知用户", order.getOrderNo(), rejectReason);
    }

    @Override
    public BigDecimal[] calculateRefundAmount(Order order, BigDecimal compensationRate) {
        BigDecimal actualAmount = order.getActualAmount();
        BigDecimal refundAmount;
        BigDecimal compensationAmount = BigDecimal.ZERO;

        if (isErrandOrder(order.getOrderType()) && compensationRate != null) {
            // 代取订单：需要扣除补偿金
            compensationAmount = actualAmount.multiply(compensationRate).setScale(2, RoundingMode.HALF_UP);
            refundAmount = actualAmount.subtract(compensationAmount);
        } else {
            // 零食订单：全额退款
            refundAmount = actualAmount;
        }

        return new BigDecimal[]{refundAmount, compensationAmount};
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void autoApproveOverdueRefunds() {
        // 1. 获取超时时间配置
        Integer autoApproveHours = systemConfigService.getConfigValueAsInteger("refund.merchant.auto_approve_hours", 2);
        Boolean autoApproveEnabled = systemConfigService.getConfigValueAsBoolean("refund.auto_approve.enabled", true);
        
        if (!autoApproveEnabled) {
            log.debug("自动审核功能已关闭");
            return;
        }

        // 2. 查询超时的退款申请
        LocalDateTime timeoutThreshold = LocalDateTime.now().minusHours(autoApproveHours);
        
        LambdaQueryWrapper<Order> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Order::getStatus, OrderStatus.REFUND_REVIEWING)
                .eq(Order::getRefundStatus, RefundStatus.REVIEWING)
                .lt(Order::getRefundApplyTime, timeoutThreshold);
        
        List<Order> overdueOrders = orderMapper.selectList(wrapper);
        
        if (overdueOrders.isEmpty()) {
            log.debug("没有超时的退款申请");
            return;
        }

        // 3. 自动处理超时订单
        BigDecimal defaultCompensationRate = systemConfigService.getConfigValueAsDecimal("refund.compensation.rate.default", new BigDecimal("0.20"));
        
        for (Order order : overdueOrders) {
            try {
                log.info("自动处理超时退款申请：订单号{}，申请时间：{}", order.getOrderNo(), order.getRefundApplyTime());
                
                BigDecimal compensationRate = isErrandOrder(order.getOrderType()) ? defaultCompensationRate : null;
                processApprovedRefund(order, compensationRate);
                
            } catch (Exception e) {
                log.error("自动处理订单{}退款失败", order.getOrderNo(), e);
            }
        }
        
        log.info("自动审核完成，处理了{}个超时退款申请", overdueOrders.size());
    }

    /**
     * 判断是否为代取订单
     */
    private boolean isErrandOrder(Integer orderType) {
        return orderType != null && orderType > 1; // 2-取快递，3-取外卖，4-代取奶咖
    }

    /**
     * 获取订单的原状态（退款审核前的状态）
     */
    private Integer getOriginalStatus(Order order) {
        // 根据订单类型和配送员信息判断原状态
        if (order.getDeliveryUserId() != null) {
            return OrderStatus.DELIVERING; // 配送中
        } else {
            return isErrandOrder(order.getOrderType()) ? OrderStatus.ACCEPTED : OrderStatus.DELIVERING;
        }
    }

    /**
     * 更新接单人收益
     * 补偿金已经记录在订单的compensationAmount字段中，
     * 实际的收益结算由其他模块处理
     */
    private void updateRiderEarning(Long riderId, BigDecimal compensationAmount) {
        if (riderId == null || compensationAmount.compareTo(BigDecimal.ZERO) <= 0) {
            return;
        }
        
        // 补偿金已经记录在订单的compensationAmount字段中
        // 后续结算时会统计所有订单的riderEarning和compensationAmount
        log.info("接单人{}获得补偿金{}元，已记录在订单中", riderId, compensationAmount);
    }

    /**
     * 获取商家ID（单商户模式：查询 user_type=3 的用户）
     */
    private Long getMerchantId() {
        try {
            LambdaQueryWrapper<com.snack.shop.entity.User> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(com.snack.shop.entity.User::getUserType, 3) // user_type=3 为商家
                   .last("limit 1");
            com.snack.shop.entity.User merchant = userMapper.selectOne(wrapper);
            return merchant != null ? merchant.getId() : null;
        } catch (Exception e) {
            log.error("获取商家ID失败", e);
            return null;
        }
    }
}
